package com.ubxtech.core.utils;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.ubxtech.core.dto.TreeNode;
import com.ubxtech.core.dto.TreeNodeComparator;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 通用转tree
 * @author Victor.Xiao
 * @since 2023-10-12 11:09
*/
@Slf4j
public class TreeUtil {
    /**
     * 构建Tree结构
     *
     * @param treeList 待转换的集合
     * @return 树结构
     */
    public static <E extends TreeNode<T>,T> List<E> buildTree(List<E> treeList) {

        //根节点集合
        List<E> trees = new ArrayList<>();
        if (CollectionUtil.isEmpty(treeList)) {
            return trees;
        }
        //转化成map结构
        Map<T,E> idMap = treeList.stream().collect(Collectors.toMap(TreeNode::getId, a -> a,(k1, k2)->k1));

        // 为每一个节点找到子节点集合
        for (E node : treeList) {
            T id = node.getId();
            T parentId = node.getParentId();
            //如果id为空则是错误节点
            if (isRoot(id)) {
                log.error("构造树结构id为空,{}", node);
                continue;
            }
            //父节点为空或者为0则为root节点
            if (isRoot(parentId)) {
                trees.add(node);
                continue;
            }
            E pNode = idMap.get(parentId);
            //没有父节点也是错误节点
            if (pNode == null) {
                log.error("构造树结构pNode为空,{}", node);
                continue;
            }
            //id和pid相等
            if (id.toString().equalsIgnoreCase(parentId.toString())) {
                log.error("构造树结构id和pid相等,{}", node);
                continue;
            }
            boolean resultFlag = pNode.getChildren().add(node);
            if (!resultFlag) {
                log.warn("树操作添加节点失败:{}" , node);
            }
        }
        trees = CollectionUtil.sort(trees,new TreeNodeComparator<>());
        return trees;
    }


    /**
     * 判断id是否为根节点
     */
    public static boolean isRoot(Object id) {
        return id == null || StrUtil.isBlank(id.toString()) || StrPool.ZERO.equals(id.toString());
    }


    public static String getTreePath(String parentTreePath, Long parentId) {
        return StrPool.COMMA + parentId + parentTreePath;
    }

    public static void main(String[] args) {
        List<TreeNode<String>> list = new ArrayList<>();
        TreeNode<String> treeNode1 = new TreeNode<>();
        treeNode1.setId("1");
        treeNode1.setParentId("");
        treeNode1.setName("1");
        treeNode1.setOrderNo(2);
        list.add(treeNode1);

        TreeNode<String> node2 = new TreeNode<>();
        node2.setId("2");
        node2.setParentId("");
        node2.setName("2");
//        node2.setOrderNo(1);
        list.add(node2);

        TreeNode<String> node3 = new TreeNode<>();
        node3.setId("3");
        node3.setParentId("1");
        node3.setName("3");
        list.add(node3);

        TreeNode<String> node4 = new TreeNode<>();
        node4.setId("4");
        node4.setParentId("3");
        node4.setName("4");
        list.add(node4);

        TreeNode<String> node5 = new TreeNode<>();
        node5.setId("5");
        node5.setParentId("3");
        node5.setName("5");
        node5.setOrderNo(4);
        list.add(node5);

        TreeNode<String> node6 = new TreeNode<>();
        node6.setId("6");
        node6.setParentId("3");
        node6.setName("6");
        node6.setOrderNo(3);
        list.add(node6);


        TreeNode<String> node7 = new TreeNode<>();
        node7.setId("7");
        node7.setParentId("");
        node7.setName("7");
        node7.setOrderNo(2);
        list.add(node7);


        List<TreeNode<String>> result = TreeUtil.buildTree(list);
//        result = CollectionUtil.sortByProperty(result, "orderNo");
        System.out.println(result.size());

}

}
